﻿using ServerCommon.Config;
using ServerCommon.Log;
using ServerCommon.Net;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GatewayServer.Server
{
    public class GatewayNet
    {
        public static readonly GatewayNet Instance = new Lazy<GatewayNet>(() => new GatewayNet(), true).Value;
        private static LogHelper log = LogHelper.GetLogger(typeof(GatewayNet));

        NetNodeManagerOuter _managerOuter;
        NetService _serviceOuter;

        NetNodeManagerInner _managerInner;
        NetService _serviceInner;

        NetNodeManager _managerGM;
        NetClient _clientGM;

        public void Init(long localGateId)
        {
            _managerOuter = new NetNodeManagerOuter();
            _managerOuter.Init();

            _managerInner = new NetNodeManagerInner();
            _managerInner.Init();

            _managerGM = new NetNodeManager();
            _managerGM.Init();

            var netConfig = ConfigManager.Instance.NetConfig["NetConfigure"];
            var gateNetConfig = netConfig["GateNetConfig"];
            var outerNetConfig = gateNetConfig["ClientService"];
            var innerNetConfig = gateNetConfig["GameService"];
            int outerConnectionCount = outerNetConfig.Value<int>("MaxConnection");
            int outerBufferSize = outerNetConfig.Value<int>("SAEABufferSize");
            int innerConnectionCount = innerNetConfig.Value<int>("MaxConnection");
            int innerBufferSize = innerNetConfig.Value<int>("SAEABufferSize");

            var serverConfig = ConfigManager.Instance.ServerConfig;
            var gateConfig = serverConfig["GatewayServer"];
            string outerIp = gateConfig.Value<string>("OuterIp");
            string innerIp = gateConfig.Value<string>("InnerIp");
            var gatewayList = gateConfig["List"].ToArray();
            bool findGate = false;
            for (int i = 0; i < gatewayList.Length; i++)
            {
                var item = gatewayList[i];
                long gateServerId = item.Value<int>("Id");
                if(gateServerId == localGateId)
                {
                    findGate = true;
                    int outerPort = item.Value<int>("OuterPort");
                    int innerPort = item.Value<int>("InnerPort");

                    _serviceOuter = new NetService();
                    _serviceOuter.Config(_managerOuter, EnumNodeServiceType.Database, outerIp, outerPort, outerConnectionCount, outerBufferSize, localGateId);
                    _serviceOuter.Start();
                    _serviceOuter.ShowPrompt();

                    _serviceInner = new NetService();
                    _serviceInner.Config(_managerInner, EnumNodeServiceType.Database, innerIp, innerPort, innerConnectionCount, innerBufferSize, localGateId);
                    _serviceInner.Start();
                    _serviceInner.ShowPrompt();
                    break;
                }
            }

            if(!findGate)
            {
                log.ErrorFormat("Can not find local gate Id-{0}", localGateId);
                return;
            }

            var clientNetConfig = netConfig["ServerCustomConfig"];
            int connectionCount = clientNetConfig.Value<int>("MaxConnection");
            int bufferSize = clientNetConfig.Value<int>("SAEABufferSize");

            var gmConfig = serverConfig["GMServer"];
            string ip = gmConfig.Value<string>("Ip");
            int port = gmConfig.Value<int>("Port");
            long gmServerId = gmConfig.Value<long>("Id");

            _clientGM = new NetClient();
            _clientGM.Config(_managerGM, ip, port, connectionCount, bufferSize, gmServerId, localGateId);
            _clientGM.Start();
            _clientGM.ShowPrompt();

            NetNodeReconnect.Instance.Init();
        }

        public void Run()
        {
            _managerOuter.DoNetMessages();
            _managerInner.DoNetMessages();
            _managerGM.DoNetMessages();
        }

        public void Stop()
        {
            NetNodeReconnect.Instance.Release();

            _managerOuter.StopNetwork();
            _managerInner.StopNetwork();
            _managerGM.StopNetwork();
        }

        public void Release()
        {
        }
    }
}
